(function(global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(function() {
            return factory(global, global.document);
        });
    } else if (typeof module !== 'undefined' && module.exports) {
        module.exports = factory(global, global.document);
    } else {
        global.Draw = factory(global, global.document);
    }
}(typeof window !== 'undefined' ? window : this, function(window, document) {

    'use strict';
    /**
     * 参数：
     * el:canvas图形的容器，可以兼容css3中的选择器
     * width:画布的宽度
     * height:画布的高度
     * position:图像的左上角坐标
     * text.content:绘制文本的内容
     * text.fontFamily:绘制文本的字体
     * text.fontSize: 绘制文本的字体大小

     * text.fillStyle:填充文本的颜色
     * text.strokeStyle:文本描边的颜色
     * text.textBaseline:文本基线对齐选项
     * text.maxWidth:绘制文本的最大宽度
     * text.x:文字左上角的X坐标
     * text.y:文字左上角的Y坐标
     * polygon.newobj:是否是新绘制的多边形
     * polygon.fill:是否需要填充
     * polygon.close:是否需要关闭
     * polygon.stroke:是否需要描边
     * polygon.fillStyle:多边形的填充样式
     * polygon.strokeStyle:多边形的描边样式
     * polygon.lineWidth:多边形的描边线条粗细
     * polygon.vertex:多边形的顶点坐标，数据类型是二位数组，如三角形的话，可以这样定义[[20,50],[20,80],[50,30]]
     * arc.x:圆心的X坐标
     * arc.y:圆心的Y坐标
     * arc.radius:圆的半径
     * arc.startAngle:圆的起始弧度
     * arc.endAngle:圆的终点弧度
     * arc.anticlockwise:是否顺时针画圆
     * arc.newobj:是否是新绘制的圆
     * arc.fill:是否需要填充
     * arc.close:是否需要关闭
     * arc.stroke:是否需要描边
     * arc.fillStyle:圆的填充样式
     * arc.strokeStyle:圆的描边样式
     * arc.lineWidth:圆的描边线条粗细
     * img.src:图片的路径
     * img.dx:目标画布的左上角在目标canvas上 X 轴的位置
     * img.dy:目标画布的左上角在目标canvas上 Y 轴的位置
     * img.dWidth:在目标画布上绘制图像的宽度
     * img.dHeight:在目标画布上绘制图像的高度
     * img.sx:需要绘制到目标上下文中的，源图像的矩形选择框的左上角 X 坐标
     * img.sy:需要绘制到目标上下文中的，源图像的矩形选择框的左上角 Y 坐标
     * img.sWidth:需要绘制到目标上下文中的，源图像的矩形选择框的宽度
     * img.sHeight:需要绘制到目标上下文中的，源图像的矩形选择框的高度
     * img.space:粒子间隔
     * animate.model:粒子运动的模式，0为分散，1为聚合
     * animate.model:粒子的对象
     * animate.time:粒子运动总时间
     * animate.speed:粒子运动速度
     * animate.space:获取图片粒子的价格
     * animate.shape:粒子的形状
     */

<<<<<<< HEAD
    var utils = require('k-kits').nodetools;
=======
    var utils = require('./utils');
>>>>>>> 79b80d0fda0a311f7fc3f7f569dd396f7facfe6c
    var TWEEN = require('@tweenjs/tween.js');
    /**
     * 初始化
     * @param  {对象} options 初始化画布的参数
     * @return {draw对象}         [返回draw对象的引用]
     */
    var Draw = function(options) {
        this.defaultOps = {
            el: '#draw',
            width: 500,
            height: 300,
            position: {
                x: 0,
                y: 0
            },
            text: {
                content: 'Hello World!',
                fontFamily: '微软雅黑',
                fontSize: '16px',
                fillStyle: '#000',
                strokeStyle: '#000',
                textAlign: 'start',
                textBaseline: 'top',
                direction: 'ltr',
                maxWidth: '50',
                x: 0,
                y: 0
            },
            polygon: {
                stroke: true,
                fillStyle: '#000',
                strokeStyle: '#000',
                fill: true,
                close: true,
                lineWidth: 1,
                newobj: true,
                vertex: [
                    [0, 0],
                    [0, 100],
                    [100, 100],
                    [100, 0],
                    [50, 50]
                ]
            },
            arc: {
                x: 100,
                y: 100,
                radius: 50,
                startAngle: 0,
                endAngle: Math.PI * 2,
                anticlockwise: false,
                stroke: true,
                fillStyle: '#000',
                strokeStyle: '#000',
                fill: true,
                close: true,
                lineWidth: 1,
                newobj: true,
            },
            img: {
                dx: 0,
                dy: 0,
                dWidth: 200,
                dHeight: 200,
                sx: 50,
                sy: 50,
                sWidth: 100,
                sHeight: 100
            },
            animate: {
                radius: 1,
                model: 1,
                object: null,
                time: 1,
                speed: .1,
                space: 1,
                shape: "square"
            }
        };
        //整合参数
        var opts = this.defaultOps;
        Object.keys(options).map(function(key) {
            opts[key] = options[key];
        });
        var container = document.querySelector(opts.el);
        var canvas = document.createElement('canvas');
        opts.context = canvas.getContext('2d');
        canvas.width = opts.width;
        canvas.height = opts.height;
        this.defaultOps = opts;
        container.appendChild(canvas);
    };

    Draw.prototype.fillText = function(options, cb) {
        var cb = arguments[arguments.length - 1];
        var opts = this.defaultOps.text;
        if (typeof options == "object") {
            Object.keys(options).map(function(key) {
                opts[key] = options[key];
            });
        }
        var ctx = this.defaultOps.context;
        ctx.font = opts.fontSize + ' ' + opts.fontFamily;
        ctx.fillStyle = opts.fillStyle;
        ctx.textAlign = opts.textAlign;
        ctx.textBaseline = opts.textBaseline;
        ctx.direction = opts.direction;
        ctx.fillText(opts.content, opts.x, opts.y);
        utils.execCallBack(cb);
        return this;
    };
    Draw.prototype.strokeText = function(options, cb) {
        var cb = arguments[arguments.length - 1];
        var opts = this.defaultOps.text;
        if (typeof options == "object") {
            Object.keys(options).map(function(key) {
                opts[key] = options[key];
            });
        }
        var ctx = this.defaultOps.context;
        ctx.font = opts.fontSize + ' ' + opts.fontFamily;
        ctx.strokeStyle = opts.strokeStyle;
        ctx.fillStyle = opts.fillStyle;
        ctx.textAlign = opts.textAlign;
        ctx.textBaseline = opts.textBaseline;
        ctx.direction = opts.direction;
        ctx.strokeText(opts.content, opts.x, opts.y);
        utils.execCallBack(cb);
        return this;
    };
    Draw.prototype.rect = function() {
        var ctx = this.defaultOps.context;
        ctx.fillStyle = "#000";
        ctx.fillRect(0, 0, 100, 100);
        ctx.fill();
    }
    Draw.prototype.polygon = function(options, cb) {
        var cb = arguments[arguments.length - 1];
        var opts = this.defaultOps.polygon;
        if (typeof options == "object") {
            Object.keys(options).map(function(key) {
                opts[key] = options[key];
            });
        }
        var ctx = this.defaultOps.context;
        var close = opts.close;
        var fill = opts.fill;
        var stroke = opts.stroke;
        var fillStyle = opts.fillStyle;
        var strokeStyle = opts.strokeStyle;
        var lineWidth = opts.lineWidth;
        var vertex = opts.vertex;
        var newobj = opts.newobj;
        if (ctx) {
            if (newobj) {
                ctx.moveTo(vertex[0][0], vertex[0][1]);
                for (var i = 1; i < vertex.length; i++) {
                    ctx.lineTo(vertex[i][0], vertex[i][1]);
                }
            } else {
                for (var i = 0; i < vertex.length; i++) {
                    ctx.lineTo(vertex[i][0], vertex[i][1]);
                }
            }

            if (close) {
                ctx.closePath();
            }

            if (fill) {
                ctx.fillStyle = fillStyle;
                ctx.fill();
            }
            if (stroke) {
                ctx.lineWidth = lineWidth;
                ctx.strokeStyle = strokeStyle;
                ctx.stroke();
            }
        } else {
            alert('the brower is not surpport canvas');
        }
        utils.execCallBack(cb);
        return this;
    }
    /**
     * @return {draw对象}   draw对象的引用
     */
    Draw.prototype.arc = function(options, cb) {
        var cb = arguments[arguments.length - 1];
        var opts = this.defaultOps.arc;
        if (typeof options == "object") {
            Object.keys(options).map(function(key) {
                opts[key] = options[key];
            });
        }
<<<<<<< HEAD

        var x = opts.x;
        var y = opts.y;
        var radius = opts.radius;
        var startAngle = opts.startAngle;
        var endAngle = opts.endAngle;
        var anticlockwise = opts.anticlockwise;
        var fill = opts.fill;
        var close = opts.close;
        var strokeStyle = opts.strokeStyle;
        var lineWidth = opts.lineWidth;
        var fillStyle = opts.fillStyle;
        var stroke = opts.stroke;
        var newobj = opts.newobj;
        var ctx = this.defaultOps.context;
        if (ctx) {
            if (newobj) {
                ctx.beginPath();
            }
            ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
            if (close) {
                ctx.closePath();
            }
            if (fill) {
                ctx.fillStyle = fillStyle;
                ctx.fill();
            }
            if (stroke) {
                ctx.strokeStyle = strokeStyle;
                ctx.lineWidth = lineWidth
                ctx.stroke();
            }
        } else {
            alert('the brower is not surpport canvas');
        }
        utils.execCallBack(cb);
        return this;
    };
    Draw.prototype.bezier = function() {
        return this;
    };
    Draw.prototype.img = function(options, cb) {
        var _this = this;
        var opts = this.defaultOps.img;
        var cb = arguments[arguments.length - 1];
        if (typeof options == "object") {
            Object.keys(options).map(function(key) {
                opts[key] = options[key];
            });
        }
        var ctx = this.defaultOps.context;

        var img = new Image();
        var sx = opts.sx;
        var sy = opts.sy;
        var sWidth = opts.sWidth;
        var sHeight = opts.sHeight;
        var dx = opts.dx;
        var dy = opts.dy;
        var dWidth = opts.dWidth;
        var dHeight = opts.dHeight;
        var width = this.defaultOps.width;
        var height = this.defaultOps.height;
        var dots = [];
        img.onload = function() {
            ctx.drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
            utils.execCallBack(cb, _this);
        }
        img.src = opts.src;
        return this;
    };
    /**
     * 动画
     *model:0是分散，1是聚合
     */
    Draw.prototype.animate = function(options) {
        var _this = this;
        var ctx = this.defaultOps.context;
        var width = this.defaultOps.width;
        var height = this.defaultOps.height;
        //整合参数
        var opts = this.defaultOps.animate;
        Object.keys(options).map(function(key) {
            opts[key] = options[key];
        });
        var dots = getDots(opts);
        var model = opts.model;
        dots.map(function(dot) {
            //初始化粒子
            if (model === 1) {
                dot.x2 = Math.random() * width;
                dot.y2 = Math.random() * height;
            } else if (model === 0) {
                dot.x2 = dot.x1;
                dot.y2 = dot.y1;
                dot.x1 = Math.random() * width;
                dot.y1 = Math.random() * height;
            } else {
                return;
            }

            dot.paint(_this);
        });
        opts.object = dots;

        requestAnimationFrame(animate);

        function getDots(options) {
            var opts = options;
            var dots = [];
            var space = opts.space; //每间隔一定个像素取一点
            var imgdata = ctx.getImageData(0, 0, width, height).data;
            ctx.clearRect(0, 0, width, height);
            for (var y = 0; y < height; y += space) {
                for (var x = 0; x < width; x += space) {
                    var i = (y * width + x) * 4; //先从左到右取点，再从上到下去点，*4是因为rgba。
                    if (imgdata[i + 3] > 128) { //根据透明度判断是否有绘画
                        var dot = new Dot();
                        dot.x1 = x;
                        dot.y1 = y;
                        dot.r = imgdata[i];
                        dot.g = imgdata[i + 1];
                        dot.b = imgdata[i + 2];
                        dot.a = imgdata[i + 3];
                        dots.push(dot);
                    }
                }
            }
            return dots;
        };

        function animate() {
            var model = opts.model;
            var t = opts.time; //总的运动时间
            var t1 = opts.speed; //每帧的时间间隔
            var dots = opts.object;
            var index = 0;
            ctx.clearRect(0, 0, width, height);
            opts.object.map(function(dot) {
                if (model == 1) {
                    dot.vx = (dot.x1 - dot.x2) / t;
                    dot.vy = (dot.y1 - dot.y2) / t;
                    //这里需要控制每个点的停止和运动
                    if (dot.pause === true) {
                        dot.x2 = dot.x1;
                        dot.y2 = dot.y1;
                    }
                    dot.x2 += dot.vx * t1;
                    dot.y2 += dot.vy * t1;
                    if (Math.abs(dot.x1 - dot.x2) < 0.01 && Math.abs(dot.y1 - dot.y2) < 0.01) {
                        dot.pause = true;
                    }
                } else if (model == 0) {
                    dot.vx = (dot.x1 - dot.x2) / t;
                    dot.vy = (dot.y1 - dot.y2) / t;
                    //这里需要控制每个点的停止和运动
                    if (dot.pause === true) {
                        dot.x2 = dot.x1;
                        dot.y2 = dot.y1;
                    }
                    dot.x2 -= dot.vx * t1;
                    dot.y2 -= dot.vy * t1;
                    if (Math.abs(dot.x1 - dot.x2) < 100 && Math.abs(dot.y1 - dot.y2) < 100) {
                        dot.pause = true;
                    }
                }
                dot.paint(_this);
            })
            requestAnimationFrame(animate);

        };

    };
    var Dot = function() {
        // dot.x1: 终点X坐标，
        // dot.y1: 终点Y坐标，
        // dot.x2: 起点X坐标，
        // dot.y2: 起点Y坐标

    }
    Dot.prototype.paint = function(draw) {
        var shape = draw.defaultOps.animate.shape;
        var ctx = draw.defaultOps.context;
        ctx.save();
        ctx.beginPath();
        ctx.fillStyle = "rgba(" + this.r + "," + this.g + "," + this.b + "," + this.a + ")";
        if (shape == "square") {
            ctx.fillRect(this.x2, this.y2, 1, 1);
        } else if (shape == "circle") {
            ctx.arc(this.x2, this.y2, this.radius, 0, Math.PI, false);
        }
        ctx.fill();
        ctx.restore();
    }
=======

        var x = opts.x;
        var y = opts.y;
        var radius = opts.radius;
        var startAngle = opts.startAngle;
        var endAngle = opts.endAngle;
        var anticlockwise = opts.anticlockwise;
        var fill = opts.fill;
        var close = opts.close;
        var strokeStyle = opts.strokeStyle;
        var lineWidth = opts.lineWidth;
        var fillStyle = opts.fillStyle;
        var stroke = opts.stroke;
        var newobj = opts.newobj;
        var ctx = this.defaultOps.context;
        if (ctx) {
            if (newobj) {
                ctx.beginPath();
            }
            ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
            if (close) {
                ctx.closePath();
            }
            if (fill) {
                ctx.fillStyle = fillStyle;
                ctx.fill();
            }
            if (stroke) {
                ctx.strokeStyle = strokeStyle;
                ctx.lineWidth = lineWidth
                ctx.stroke();
            }
        } else {
            alert('the brower is not surpport canvas');
        }
        utils.execCallBack(cb);
        return this;
    };
    Draw.prototype.bezier = function() {
        return this;
    };
    Draw.prototype.img = function(options, cb) {
        var _this = this;
        var opts = this.defaultOps.img;
        var cb = arguments[arguments.length - 1];
        if (typeof options == "object") {
            Object.keys(options).map(function(key) {
                opts[key] = options[key];
            });
        }
        var ctx = this.defaultOps.context;

        var img = new Image();
        var sx = opts.sx;
        var sy = opts.sy;
        var sWidth = opts.sWidth;
        var sHeight = opts.sHeight;
        var dx = opts.dx;
        var dy = opts.dy;
        var dWidth = opts.dWidth;
        var dHeight = opts.dHeight;
        var width = this.defaultOps.width;
        var height = this.defaultOps.height;
        var dots = [];
        img.onload = function() {
            ctx.drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
            utils.execCallBack(cb, _this);
        }
        img.src = opts.src;
        return this;
    };
    /**
     * 动画
     *model:0是分散，1是聚合
     */
    Draw.prototype.animate = function(options) {
        var _this = this;
        var ctx = this.defaultOps.context;
        var width = this.defaultOps.width;
        var height = this.defaultOps.height;
        //整合参数
        var opts = this.defaultOps.animate;
        Object.keys(options).map(function(key) {
            opts[key] = options[key];
        });
        var dots = getDots(opts);
        var model = opts.model;
        dots.map(function(dot) {
            //初始化粒子
            if (model === 1) {
                dot.x2 = Math.random() * width;
                dot.y2 = Math.random() * height;
            } else if (model === 0) {
                dot.x2 = dot.x1;
                dot.y2 = dot.y1;
                dot.x1 = Math.random() * width;
                dot.y1 = Math.random() * height;
            } else {
                return;
            }

            dot.paint(_this);
        });
        opts.object = dots;

        requestAnimationFrame(animate);

        function getDots(options) {
            var opts = options;
            var dots = [];
            var space = opts.space; //每间隔一定个像素取一点
            var imgdata = ctx.getImageData(0, 0, width, height).data;
            ctx.clearRect(0, 0, width, height);
            for (var y = 0; y < height; y += space) {
                for (var x = 0; x < width; x += space) {
                    var i = (y * width + x) * 4; //先从左到右取点，再从上到下去点，*4是因为rgba。
                    if (imgdata[i + 3] > 128) { //根据透明度判断是否有绘画
                        var dot = new Dot();
                        dot.x1 = x;
                        dot.y1 = y;
                        dot.r = imgdata[i];
                        dot.g = imgdata[i + 1];
                        dot.b = imgdata[i + 2];
                        dot.a = imgdata[i + 3];
                        dots.push(dot);
                    }
                }
            }
            return dots;
        };

        function animate() {
            var model = opts.model;
            var t = opts.time; //总的运动时间
            var t1 = opts.speed; //每帧的时间间隔
            var dots = opts.object;
            var index = 0;
            ctx.clearRect(0, 0, width, height);
            opts.object.map(function(dot) {
                if (model == 1) {
                    dot.vx = (dot.x1 - dot.x2) / t;
                    dot.vy = (dot.y1 - dot.y2) / t;
                    //这里需要控制每个点的停止和运动
                    if (dot.pause === true) {
                        dot.x2 = dot.x1;
                        dot.y2 = dot.y1;
                    }
                    dot.x2 += dot.vx * t1;
                    dot.y2 += dot.vy * t1;
                    if (Math.abs(dot.x1 - dot.x2) < 0.01 && Math.abs(dot.y1 - dot.y2) < 0.01) {
                        dot.pause = true;
                    }
                } else if (model == 0) {
                    dot.vx = (dot.x1 - dot.x2) / t;
                    dot.vy = (dot.y1 - dot.y2) / t;
                    //这里需要控制每个点的停止和运动
                    if (dot.pause === true) {
                        dot.x2 = dot.x1;
                        dot.y2 = dot.y1;
                    }
                    dot.x2 -= dot.vx * t1;
                    dot.y2 -= dot.vy * t1;
                    if (Math.abs(dot.x1 - dot.x2) < 100 && Math.abs(dot.y1 - dot.y2) < 100) {
                        dot.pause = true;
                    }
                }
                dot.paint(_this);
            })

            // var dot = dots[0];

            // var interation = setInterval(function() {
            //   index++;
            //   if (index >= dots.length) {
            //     clearInterval(interation);
            //   }
            //   dot = dots[index];
            //   if (model == 1) {
            //     dot.vx = (dot.x1 - dot.x2) / t;
            //     dot.vy = (dot.y1 - dot.y2) / t;
            //     //这里需要控制每个点的停止和运动
            //     if (dot.pause === true) {
            //       dot.x2 = dot.x1;
            //       dot.y2 = dot.y1;
            //     }
            //     dot.x2 += dot.vx * t1;
            //     dot.y2 += dot.vy * t1;
            //     if (Math.abs(dot.x1 - dot.x2) < 0.01 && Math.abs(dot.y1 - dot.y2) < 0.01) {
            //       dot.pause = true;
            //     }
            //   } else if (model == 0) {
            //     dot.vx = (dot.x1 - dot.x2) / t;
            //     dot.vy = (dot.y1 - dot.y2) / t;
            //     //这里需要控制每个点的停止和运动
            //     if (dot.pause === true) {
            //       dot.x2 = dot.x1;
            //       dot.y2 = dot.y1;
            //     }
            //     dot.x2 -= dot.vx * t1;
            //     dot.y2 -= dot.vy * t1;
            //     if (Math.abs(dot.x1 - dot.x2) < 100 && Math.abs(dot.y1 - dot.y2) < 100) {
            //       dot.pause = true;
            //     }
            //   }
            //   dot.paint(_this);
            // }, 100);

            requestAnimationFrame(animate);

        };

    };
    var Dot = function() {
        // dot.x1: 终点X坐标，
        // dot.y1: 终点Y坐标，
        // dot.x2: 起点X坐标，
        // dot.y2: 起点Y坐标

    }
    Dot.prototype.paint = function(draw) {
        var shape = draw.defaultOps.animate.shape;
        var ctx = draw.defaultOps.context;
        ctx.save();
        ctx.beginPath();
        ctx.fillStyle = "rgba(" + this.r + "," + this.g + "," + this.b + "," + this.a + ")";
        if (shape == "square") {
            ctx.fillRect(this.x2, this.y2, 1, 1);
        } else if (shape == "circle") {
            ctx.arc(this.x2, this.y2, this.radius, 0, Math.PI, false);
        }
        ctx.fill();
        ctx.restore();
    }
>>>>>>> 79b80d0fda0a311f7fc3f7f569dd396f7facfe6c
    return Draw;
}));